package com.xiaodou.mjf.infrastructure.payeco;

import com.xiaodou.mjf.infrastructure.payeco.encrypt.RSA;
import com.xiaodou.mjf.infrastructure.payeco.encrypt.TripleDes;
import com.xiaodou.mjf.infrastructure.payeco.util.SslConnection;
import com.xiaodou.mjf.infrastructure.payeco.util.Strings;
import com.xiaodou.mjf.infrastructure.payeco.util.Util;
import com.xiaodou.mjf.infrastructure.payeco.version2.MsgBean;
import com.xiaodou.mjf.infrastructure.payeco.version2.MsgBody;
import org.apache.log4j.Logger;

import java.net.HttpURLConnection;

/**
 * 付款工具类
 * Created by Alvin on 2015/4/3.
 */
public class PayUtils {
    private static Logger logger = Logger.getLogger(PayUtils.class.getName());

//    private static String dna_pub_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqWSfUW3fSyoOYzOG8joy3xldpBanLVg8gEDcvm9KxVjqvA/qJI7y0Rmkc1I7l9vAfWtNzphMC+wlulpaAsa/4PbfVj+WhoNQyhG+m4sP27BA8xuevNT9/W7/2ZVk4324NSowwWkaqo1yuZe1wQMcVhROz2h+g7j/uZD0fiCokWwIDAQAB";//公钥
//    //    private static String mer_pfx_key = "E:\\doc-xd\\payeco\\互联网金融_20150326\\代收付系统对接文档\\易联代收付平台接口接入文档v2.1.6及demo\\yilian.pfx";//私钥
//    private static String mer_pfx_key = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKpZJ9Rbd9LKg5jM4byOjLfGV2kFqctWDyAQNy+b0rFWOq8D+okjvLRGaRzUjuX28B9a03OmEwL7CW6WloCxr/g9t9WP5aGg1DKEb6biw/bsEDzG5681P39bv/ZlWTjfbg1KjDBaRqqjXK5l7XBAxxWFE7PaH6DuP+5kPR+IKiRbAgMBAAECgYAfDloAkRxrRZhwRwnwglyNNI/DCdFGzM29Hrew6kujIQFZ3vPSBL3mb9/B7c6PhlGIpdpe/ywAIxw5GSMfG0XlQ6umgPSsxF6TaRCXkBE1B1QYn5L4jVgHkszTRMCXkTybtaxEqEh6nhA6Krj4Y5ki1wpDpwHToTUYwz3RHuxdgQJBAN8hkxIhQ0ERALsrOWRZoishT9Ci5BxUtCYwKKw4Und1w3ywvxT28kDO2tp8aZ9/JVcHcRW04I+MmS0ZEPzGYNECQQDDcRpeVL6DLC/+fWhsUK6PixSmfH+roZURpJXlRPmQlxQwluoaQ2b/KUouujycnsphXIIpWHCZenfrJrS1yB1rAkBgU/lPOWb0fyempil3xi55mj7/3mLGTFcdqWrVttb7Va7YdOF5Zob9LZBUBKQAxH5VTRQn/9d2gYdbbdfkmKwRAkEAljVaP7/AAE64wE4gMIc98kLBZ0duVDnGuR2WuvPtHuyObt2+JNtC0L8qLYmjRfhgsL2JqD85oyvV+Jvx7XhU6wJBALIT5T+T3HdFRXlRAH12X74VXOnfHZ79sU/NNDBBtRN2AKfNo/I9g9xV7hZiVGTWEuDK8NImWYBU33PejWCZdS8=";//私钥
//    //    private static String mer_pfx_pass = "11111111";//私钥密码
//    private static String url = "https://58.248.38.253:9444/service";//测试环境下单地址
//	private static String url = "https://agent.payeco.com/service";//生产环境下单地址

    private static String VERSION = "2.1";
    private static String BATCH_PAYMENT = "100001";
    private static String PAYMENT_QUERY = "100002";

    /**
     * TODO:代付
     * 商户通过易联付款给客户，一般用于提现等。
     *
     * @param batchNo       批次号
     * @param bankAccountNo 银行账号
     * @param accountName   银行账号名
     * @param amount        金额
     * @param bankName      开户行名称
     * @param accountProp   账号性质:0:私人,1:公司 默认0
     * @param orderId       关联订单id
     * @throws Exception
     */
    public static void pay(String batchNo, String bankAccountNo, String accountName, double amount, String bankName, String accountProp, String orderId) throws Exception {

        MsgBean req_bean = new MsgBean();
        req_bean.setVERSION(VERSION);
        req_bean.setMSG_TYPE(BATCH_PAYMENT);//批量代付
        req_bean.setBATCH_NO(batchNo);//每笔订单不可重复，建议：公司简称缩写+yymmdd+流水号
        //TODO:以下待做
        req_bean.setUSER_NAME(Payeco.IF.user_name);//TODO:系统后台用户名

        int sn = 1;
        MsgBody body = new MsgBody();
        body.setSN(String.format("%06d", sn));//流水号，同一批次不重复即可
        body.setACC_NO(bankAccountNo);//必填
        body.setACC_NAME(accountName);//必填
        body.setAMOUNT(String.valueOf(amount));//必填
        /*body.setACC_PROVINCE("上海市");
        body.setACC_CITY("上海市");*/
        body.setBANK_NAME(bankName);
        if ("1".equals(accountProp)) {
            body.setACC_PROP("0");
        } else {
            body.setACC_PROP("1");
        }
        body.setMER_ORDER_NO(orderId);
        req_bean.getBODYS().add(body);

        String res = sendAndRead(signANDencrypt(req_bean));

        MsgBean res_bean = decryptANDverify(res);

        if ("0000".equals(res_bean.getTRANS_STATE())) {
            logger.info("请求成功");
        }
        logger.info(res_bean.toXml());
    }

    /**
     * TODO:代付查询
     * 查询代付交易结果。
     *
     * @param batchNo 批次号
     * @param orderId 商户订单流水号(关联订单ID)
     * @throws Exception
     */
    public static boolean payQuery(String batchNo, String orderId) throws Exception {

        MsgBean req_bean = new MsgBean();
        req_bean.setVERSION(VERSION);
        req_bean.setMSG_TYPE(PAYMENT_QUERY);//待付查询
//        req_bean.setBATCH_NO("A7762217");//同代付交易请求批次号
        req_bean.setBATCH_NO(batchNo);//同代付交易请求批次号
        req_bean.setUSER_NAME(Payeco.IF.user_name);//TODO:系统后台用户名

        MsgBody body = new MsgBody();
        body.setQUERY_NO_FLAG("0");//查询请求时填写；        0：使用批次号查询 （默认）；        1：使用商户订单号来查询

        body.setMER_ORDER_NO(orderId);//商户订单流水号
        req_bean.getBODYS().add(body);
        String res = sendAndRead(signANDencrypt(req_bean));

        System.out.println("res: " + res);
        MsgBean res_bean = decryptANDverify(res);

        if ("0000".equals(res_bean.getTRANS_STATE())) {
            logger.info("请求成功");
            return true;
        }
        logger.info(res_bean.toXml());
        return false;
    }

    private static MsgBean decryptANDverify(String res) {

        String msg_sign_enc = res.split("\\|")[0];
        String key_3des_enc = res.split("\\|")[1];

        //解密密钥
        String key_3des = RSA.decrypt(key_3des_enc, Payeco.IF.private_key);

        //解密报文
        String msg_sign = TripleDes.decrypt(key_3des, msg_sign_enc);
        MsgBean res_bean = new MsgBean();
        res_bean.toBean(msg_sign);
        logger.info("res:" + res_bean.toXml());

        //验签
        String dna_sign_msg = res_bean.getMSG_SIGN();
        res_bean.setMSG_SIGN("");
        String verify = Strings.isNullOrEmpty(res_bean.getVERSION()) ? res_bean.toXml() : res_bean.toSign();
        logger.info("verify:" + verify);
        if (!RSA.verify(dna_sign_msg, Payeco.IF.payment_public_key, verify)) {
            logger.error("验签失败");
            res_bean.setTRANS_STATE("00A0");
        }
        return res_bean;
    }

    private static String signANDencrypt(MsgBean req_bean) {

        //商户签名

        System.out.println("before sign xml ==" + req_bean.toSign());
        System.out.println("msg sign = " + RSA.sign(req_bean.toSign(), Payeco.IF.private_key));
        req_bean.setMSG_SIGN(RSA.sign(req_bean.toSign(), Payeco.IF.private_key));
        logger.info("req:" + req_bean.toXml());

        //加密报文
        String key = Util.generateKey(9999, 24);
        logger.info("key:" + key);
        String req_body_enc = TripleDes.encrypt(key, req_bean.toXml());
        logger.info("req_body_enc:" + req_body_enc);
        //加密密钥
        String req_key_enc = RSA.encrypt(key, Payeco.IF.payment_public_key);
        logger.info("req_key_enc:" + req_key_enc);
        logger.info("signANDencrypt:" + req_body_enc + "|" + req_key_enc);
        return req_body_enc + "|" + req_key_enc;

    }

    public static String sendAndRead(String req) {

        try {
            HttpURLConnection connect = new SslConnection().openConnection(Payeco.IF.payment_url);

            connect.setReadTimeout(30000);
            connect.setConnectTimeout(10000);

            connect.setRequestMethod("POST");
            connect.setDoInput(true);
            connect.setDoOutput(true);
            connect.connect();


            byte[] put = req.getBytes("UTF-8");
            connect.getOutputStream().write(put);

            connect.getOutputStream().flush();
            connect.getOutputStream().close();
            String res = SslConnection.read(connect);

            connect.getInputStream().close();
            connect.disconnect();

//			String res = new SslConnection().connect(url);

            return res;
        } catch (Exception e) {
            logger.error(Strings.getStackTrace(e));
        }
        return "";
    }
}
